#include <QQmlContext>
#include <QGuiApplication>
#include <QQuickWindow>
#include <QThreadPool>
#include <QProcess>
#include <QDir>
#include <QDebug>
#include <QTranslator>
#include <QDirIterator>
#include <QJsonDocument>
#include <QJsonArray>
#include "applicationengine.h"
#include <QQmlPropertyMap>
#include "path.h"

QQuickWindow * __Quick_window = Q_NULLPTR;

extern Path * __Path;

static void setup()
{
    QString filePath = qApp->property("startup").toString();
    if (filePath.isEmpty())
        return;

    QThreadPool::globalInstance()->waitForDone();
    QProcess::startDetached(QDir::toNativeSeparators(filePath), QStringList());
}

ApplicationEngine::ApplicationEngine(QObject *parent) : QQmlApplicationEngine(parent)
{

}

int ApplicationEngine::create()
{
    qAddPostRoutine(setup);

    QDir::setCurrent(QGuiApplication::applicationDirPath());

    this->setOfflineStoragePath(__Path->storage());

    if (!__Path->mkpath(this->offlineStoragePath())) {
        qWarning() << "create storage path failed.";
    }




    this->addPluginPath(QCoreApplication::applicationDirPath());

#ifdef Q_OS_WIN
    connect(&m_tray, &QSystemTrayIcon::activated, [](QSystemTrayIcon::ActivationReason reason){
        if (reason == QSystemTrayIcon::DoubleClick) {

            if (__Quick_window) {
                __Quick_window->setVisible(!__Quick_window->isVisible());
            }
        }
    });
#endif

    if (!QFile::exists("qrc:/favicon.png")) {
         QGuiApplication::setWindowIcon(QIcon(":/favicon.png"));
#ifdef Q_OS_WIN
         m_tray.setIcon(QIcon(":/favicon.png"));
         m_tray.show();
#endif
    }

    QTranslator translator;

    QDirIterator itor(":/translations/", QStringList("*.qm"), QDir::Files, QDirIterator::Subdirectories);


    while (itor.hasNext()) {
        itor.next();
        // ":/translations/zh-cn/qt_zh_CN.qm"
        translator.load(itor.filePath());
    }


    qApp->installTranslator(&translator);

    connect(this, SIGNAL(warnings(QList<QQmlError>)), this, SLOT(logWarnings(QList<QQmlError>)));
    connect(this, SIGNAL(objectCreated(QObject*,QUrl)), this, SLOT(qmlObjectCreated(QObject*,QUrl)));


    QQmlPropertyMap usinfomap;
    this->rootContext()->setContextProperty("usinfo", &usinfomap);

    this->load(QUrl("qrc:/qml/index.qml"));

#if !defined(QT_DEBUG)
    //qInstallMessageHandler(redirection);
#endif // _DEBUG

   return  qApp->exec();
}

void ApplicationEngine::logWarnings(const QList<QQmlError> &warnings)
{
    QStringList ws;

    Q_FOREACH(QQmlError e, warnings) {
        ws << e.toString();
    }

    QJsonDocument document(QJsonArray::fromStringList(ws));

    qWarning() << document.toJson();
}

void ApplicationEngine::qmlObjectCreated(QObject *object, const QUrl &url)
{
    __Quick_window = qobject_cast<QQuickWindow *>(object);

    if (!__Quick_window) {
        return;
    }

    if (!QFile::exists(":/favicon.png")) {
        __Quick_window->setIcon(QIcon(":/favicon.png"));
    }
}


void ApplicationEngine::redirection(QtMsgType type, const QMessageLogContext &context, const QString &description)
{
    QString message = qFormatLogMessage(type, context, description);

    QVariantMap object;
    switch (type) {
    case QtDebugMsg:
        object.insert("type", "D");
        break;
    case QtInfoMsg:
        object.insert("type", "I");
        break;
    case QtWarningMsg:
        object.insert("type", "W");
        break;
    case QtCriticalMsg:
        object.insert("type", "C");
        break;
    case QtFatalMsg:
        object.insert("type", "F");
    }

    object.insert("line", context.line);
    object.insert("file", context.file);
    object.insert("function", context.function);
    object.insert("message", message);

    if (__Quick_window) {
        QMetaObject::invokeMethod(__Quick_window, "logMessageReported", Q_ARG(QVariant, object));
    }
}

